package pe.edu.pucp.Seguridad.DAO;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import pe.edu.pucp.Modelo.Aeropuerto;
import pe.edu.pucp.Modelo.Ciudad;
import pe.edu.pucp.Modelo.Conexion;
import pe.edu.pucp.Modelo.Continente;
import pe.edu.pucp.Modelo.EstadoPassword;
import pe.edu.pucp.Modelo.EstadoUsuario;
import pe.edu.pucp.Modelo.Pais;
import pe.edu.pucp.Modelo.Password;
import pe.edu.pucp.Modelo.Perfil;
import pe.edu.pucp.Modelo.TipoCorreo;
import pe.edu.pucp.Modelo.TipoDocumento;
import pe.edu.pucp.Modelo.Usuario;
import pe.edu.pucp.Util.Constante;
import pe.edu.pucp.Util.HibernateUtil;

public class UsuarioDAO {
    
    public Usuario guardarUsuario(Usuario p){     
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  null;
        try{
            tx = session.beginTransaction();
            session.save(p);                                              
            tx.commit();  
        }catch(Exception e) {
            if (tx!=null) {
                tx.rollback();
            }
        } finally {
            session.close();                      
            return p;       
        }
    }    

    public Usuario modificarUsuario(Usuario p){ 
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  null;
        try{
            tx =  session.beginTransaction();
            session.update(p);           
            tx.commit();
        }catch(Exception e) {
            if (tx!=null) {
                tx.rollback();
            }
        } finally {        
            session.close();                      
            return p;  
        }
    }      
    
    
    public EstadoPassword buscarEstadoPass(int idestado){
        EstadoPassword a = new EstadoPassword();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from EstadoPassword where idestado = :id");
        query.setInteger("id", idestado);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (EstadoPassword) iter.next();        
        }

        tx.commit();

        session.close();
        return a;
      
    }    
   
    public boolean existeCorreo(String correo, int idtipo, int idusuario){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Usuario where idtipocorreo = :id and correo = :mail and idusuario<>:iduser");
        query.setInteger("id", idtipo);
        query.setString("mail", correo);
        query.setInteger("iduser", idusuario);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();

        session.close();
        return existe;
              
    }       
    
    public boolean passwordUsado(String pass,int usr){
        boolean existe=false;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createSQLQuery("select cast(count(*) as int) from password where idusuario = :usr and pass = :cad");        
        query.setInteger("usr", usr);
        query.setString("cad", pass);        
        List lista = query.list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {                           
            existe = (int) iter.next() > 0;                                          
        }                         
        tx.commit();

        session.close();
        return existe;        
    }
    
    
    public boolean existeCorreo(String correo, int idtipo){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from Usuario where idtipocorreo = :id and correo = :mail");
        query.setInteger("id", idtipo);
        query.setString("mail", correo);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();
        session.close();
        return existe;      
    }     

    public boolean existeDNI(String numdoc, int idtipo, int idusuario){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from Usuario where idtipodoc = :id and documento = :doc and idusuario<>:iduser");
        query.setInteger("id", idtipo);
        query.setString("doc", numdoc);
        query.setInteger("iduser", idusuario);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();

        session.close();
        return existe;
       
    }      
    
    public boolean existeDNI(String numdoc, int idtipo){
        boolean existe;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from Usuario where idtipodoc = :id and documento = :doc");
        query.setInteger("id", idtipo);
        query.setString("doc", numdoc);
        List lista = query.list();
        Iterator iter = lista.iterator();
        existe =iter.hasNext();                            
        tx.commit();

        session.close();
        return existe;
      
    }      
             
    public void guardarPassword(Password p){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx =  session.beginTransaction();

        session.save(p);
        tx.commit();
        
        session.close();            
      
    }  
    
    public Usuario buscarUsuario(String usr){
        Usuario a = null;
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();                        
        Query query = session.createQuery("from Usuario where nombusr = :nombre");
        query.setString("nombre", usr);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Usuario) iter.next();        
            Hibernate.initialize(a.getPerfil());
            Hibernate.initialize(a.getPerfil().getPermisos());
            Hibernate.initialize(a.getPerfil().getUsuarios());
            Hibernate.initialize(a.getPerfil().getEstadoPerfil());              
            Hibernate.initialize(a.getEstadoUsuario());
            Hibernate.initialize(a.getAeropuerto());
            Hibernate.initialize(a.getAeropuerto().getCiudad());
            Hibernate.initialize(a.getAeropuerto().getCiudad().getPais().getContinente());                
            Hibernate.initialize(a.getConexion());
            Hibernate.initialize(a.getTipoCorreo());
            Hibernate.initialize(a.getTipoDocumento());                
        }

        tx.commit();

        session.close();
        return a;
              
    }    
  
    public Usuario buscarUsuario(int id){
        Usuario a = new Usuario();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();                        
        
        Query query = session.createQuery("from Usuario where idusuario = :id");
        query.setInteger("id", id);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Usuario) iter.next();        
            Hibernate.initialize(a.getPerfil());
            Hibernate.initialize(a.getPerfil().getPermisos());
            Hibernate.initialize(a.getPerfil().getUsuarios());
            Hibernate.initialize(a.getPerfil().getEstadoPerfil());              
            Hibernate.initialize(a.getEstadoUsuario());
            Hibernate.initialize(a.getAeropuerto());
            Hibernate.initialize(a.getAeropuerto().getCiudad());
            Hibernate.initialize(a.getAeropuerto().getCiudad().getPais().getContinente());                
            Hibernate.initialize(a.getConexion());
            Hibernate.initialize(a.getTipoCorreo());
            Hibernate.initialize(a.getTipoDocumento());                
        }

        tx.commit();

        session.close();
        return a;
       
    }      
    
    
     public Password buscarPassActual(int usr){
        Password a = new Password();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();                            
        Query query = session.createQuery("from Password where idusuario = :usr and idestado = :est");
        query.setInteger("usr", usr);
        query.setInteger("est", Constante.ESTADO_PASSWORD_ACTIVO);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Password) iter.next();        
            Hibernate.initialize(a.getEstadoPassword());                               
        }

        tx.commit();

        session.close();
        return a;
      
    }    
    
    
    public ArrayList<Continente> listarContinente(){
        ArrayList<Continente> listaContinente = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
                    
        String q = "select ct from Continente ct order by ct.idcontinente";        
        
        Query query = session.createQuery(q);    
        List lista = query.list();
        Iterator iter = lista.iterator(); 
        while (iter.hasNext()) {    
            Continente a = (Continente) iter.next();
            listaContinente.add(a);
        }
        
        tx.commit();
        session.close();

        return listaContinente;
    }      
            
   
    public ArrayList<Pais> listarPais(int idcont){
        ArrayList<Pais> listaPais = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        String q = "select p from Pais p where p.continente.idcontinente = :id order by p.idpais";        
        
        Query query = session.createQuery(q);       
        query.setInteger("id", idcont);
        List lista = query.list();
        Iterator iter = lista.iterator();        
        while (iter.hasNext()) {    
            Pais a = (Pais) iter.next();
            Hibernate.initialize(a.getContinente());
            listaPais.add(a);
        }
        
        tx.commit();
        session.close();

        return listaPais;
    }       
    
    public ArrayList<Ciudad> listarCiudad(int idpa){
        ArrayList<Ciudad> listaCiudad = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        String q = "select c from Ciudad c where c.pais.idpais = :id order by c.idciudad";         
        
        Query query = session.createQuery(q);          
        query.setInteger("id", idpa);
        List lista = query.list();        
        Iterator iter = lista.iterator(); 
        while (iter.hasNext()) {    
            Ciudad a = (Ciudad) iter.next();
            Hibernate.initialize(a.getPais());
            Hibernate.initialize(a.getPais().getContinente());
            listaCiudad.add(a);
        }
        
        tx.commit();
        session.close();

        return listaCiudad;
    }    
    
    public ArrayList<Aeropuerto> listarAeropuerto(int idciu){
        ArrayList<Aeropuerto> listaAeropuerto = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        String q = "select a from Aeropuerto a where a.ciudad.idciudad = :id order by a.idaeropuerto";                    
        Query query = session.createQuery(q);        
        query.setInteger("id", idciu);
        List lista = query.list();        
        Iterator iter = lista.iterator(); 
        while (iter.hasNext()) {    
            Aeropuerto a = (Aeropuerto) iter.next();
            Hibernate.initialize(a.getCiudad());
            Hibernate.initialize(a.getCiudad().getPais());
            Hibernate.initialize(a.getCiudad().getPais().getContinente());
            listaAeropuerto.add(a);
        }
        
        tx.commit();
        session.close();

        return listaAeropuerto;
    }    
   
    public ArrayList<TipoDocumento> listarTipoDoc(){
        ArrayList<TipoDocumento> listaTipoDoc = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from TipoDocumento order by idtipodoc").list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            TipoDocumento a = (TipoDocumento) iter.next();
            listaTipoDoc.add(a);
        }
        
        tx.commit();
        session.close();

        return listaTipoDoc;
    }      
 
    public ArrayList<TipoCorreo> listarTipoCorreo(){
        ArrayList<TipoCorreo> listaCorreo = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from TipoCorreo order by idtipocorreo").list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            TipoCorreo a = (TipoCorreo) iter.next();
            listaCorreo.add(a);
        }
        
        tx.commit();
        session.close();

        return listaCorreo;
    }     
    
    public ArrayList<EstadoUsuario> listarEstado(){
        ArrayList<EstadoUsuario> listaEstado = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from EstadoUsuario order by idestado").list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            EstadoUsuario a = (EstadoUsuario) iter.next();        
            listaEstado.add(a);
        }
        
        tx.commit();
        session.close();

        return listaEstado;
    }        

    public ArrayList<Perfil> listarPerfil(){
        ArrayList<Perfil> listaPerfil = new ArrayList<>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        List lista = session.createQuery("from Perfil order by idperfil").list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            Perfil a = (Perfil) iter.next();   
            Hibernate.initialize(a.getPermisos());            
            Hibernate.initialize(a.getUsuarios());            
            Hibernate.initialize(a.getEstadoPerfil());             
            listaPerfil.add(a);
        }
        
        tx.commit();
        session.close();

        return listaPerfil;
    }      
    
    public Perfil buscarPerfil(int idperfil){
        Perfil a = new Perfil();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        Query query = session.createQuery("from Perfil where idperfil = :id ");
        query.setInteger("id", idperfil);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Perfil) iter.next();  
            Hibernate.initialize(a.getPermisos());            
            Hibernate.initialize(a.getUsuarios());            
            Hibernate.initialize(a.getEstadoPerfil());              
        }        
        tx.commit();

        session.close();
        return a;

    } 
    
    public EstadoUsuario buscarEstado(int idestado){
        EstadoUsuario a = new EstadoUsuario();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from EstadoUsuario where idestado = :id");
        query.setInteger("id", idestado);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (EstadoUsuario) iter.next();        
        }

        tx.commit();

        session.close();
        return a;
      
    } 

    
    
    public Conexion buscarEstadoConexion(int idconexion){
        Conexion a = new Conexion();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from Conexion where idconexion = :id");
        query.setInteger("id", idconexion);
        List lista = query.list();
        Iterator iter = lista.iterator();
        if (iter.hasNext()) {    
            a = (Conexion) iter.next();        
        }

        tx.commit();

        session.close();
        return a;
      
    }     
    
    public ArrayList<Usuario> listarUsuario(String nomb, int cont, int pais, int ciud, int estd)
    {
        ArrayList<Usuario> listaResultados = new ArrayList<>();       
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        
        String q="select u from Usuario u where (upper(u.nombre) like '%'||:nomb||'%' or upper(u.appaterno) like '%'||:nomb||'%') ";
        if (ciud>0){ q+="and u.aeropuerto.ciudad.idciudad = :ciud "; }
        if (pais>0){ q+="and u.aeropuerto.ciudad.pais.idpais = :pais "; }
        if (cont>0){ q+="and u.aeropuerto.ciudad.pais.continente.idcontinente = :cont "; }
        if (estd>0){ q+="and u.estadoUsuario.idestado = :estd ";}        
        q+="order by u.idusuario ";
        Query query = session.createQuery(q);            
        query.setString("nomb", nomb); 
        if (ciud>0){ query.setInteger("ciud", ciud); }
        if (pais>0){ query.setInteger("pais", pais); }
        if (cont>0){ query.setInteger("cont", cont); }
        if (estd>0){ query.setInteger("estd", estd); }
                       
        List lista = query.list();
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            Usuario p = (Usuario) iter.next();
            Hibernate.initialize(p.getPerfil());
            Hibernate.initialize(p.getPerfil().getPermisos());
            Hibernate.initialize(p.getPerfil().getUsuarios());
            Hibernate.initialize(p.getPerfil().getEstadoPerfil());                    
            Hibernate.initialize(p.getEstadoUsuario());
            Hibernate.initialize(p.getAeropuerto().getCiudad());
            Hibernate.initialize(p.getAeropuerto().getCiudad().getPais());
            Hibernate.initialize(p.getAeropuerto().getCiudad().getPais().getContinente());
            Hibernate.initialize(p.getConexion());
            Hibernate.initialize(p.getTipoCorreo());
            Hibernate.initialize(p.getTipoDocumento());
            listaResultados.add(p);
        }        
        tx.commit();

        session.close();
        return listaResultados;

    }     
    
    public ArrayList<Usuario> listarUsuario()
    {
        ArrayList<Usuario> listaResultados = new ArrayList<>();       
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        List lista = session.createQuery("select u from Usuario u order by u.idusuario").list();        
        Iterator iter = lista.iterator();
        while (iter.hasNext()) {    
            Usuario p = (Usuario) iter.next();
            Hibernate.initialize(p.getPerfil());
            Hibernate.initialize(p.getPerfil().getPermisos());
            Hibernate.initialize(p.getPerfil().getUsuarios());
            Hibernate.initialize(p.getPerfil().getEstadoPerfil());                    
            Hibernate.initialize(p.getEstadoUsuario());
            Hibernate.initialize(p.getAeropuerto());
            Hibernate.initialize(p.getAeropuerto().getCiudad().getPais());
            Hibernate.initialize(p.getAeropuerto().getCiudad().getPais().getContinente());
            Hibernate.initialize(p.getConexion());
            Hibernate.initialize(p.getTipoCorreo());
            Hibernate.initialize(p.getTipoDocumento());
            listaResultados.add(p);
        }        
        tx.commit();

        session.close();
        return listaResultados;
         
    }    
}
